/*********************************************************
 * File:CheckboxTreeView.java
 * 
 * Version 1.0
 * 
 * Date     2004-1-17
 * Author   HuangYong
 * 
 * Copyright (C) 2003 VandaGroup.
 * all rights reserved.
 * 
 ********************************************************/

package com.vandagroup.portal.menu.treeview;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Vector;

import javax.servlet.jsp.JspWriter;

import com.vandagroup.common.po.PortalPO;
import com.vandagroup.common.util.Paras;

/**
 * @author HuangYong 說明：
 */
public class CheckboxTreeView {
	private String contexPath = "..";

	/**
	 * @return Returns the contexPath.
	 */
	public String getContexPath() {
		return contexPath;
	}

	/**
	 * @param contexPath
	 *            The contexPath to set.
	 */
	public void setContexPath(String contexPath) {
		this.contexPath = contexPath;
	}

	/**
	 * Create Date : 2004-1-17
	 */
	public CheckboxTreeView() {
		super();
	}

	/**
	 * 構造函數
	 * 
	 * @param title
	 * @param tableName
	 * @param colName
	 * @param textColName
	 * @param parentColName
	 * @param parentColValue
	 * @param checkboxName
	 * @param whereClause
	 * @throws Exception
	 *             Create Date : 2004-2-9
	 */
	public CheckboxTreeView(String title, String tableName, String colName,
			String textColName, String parentColName, String parentColValue,
			String checkboxName, String whereClause) throws Exception {

		setTitle(title);
		setTableName(tableName);
		setColName(colName);
		setTextColName(textColName);
		setParentColName(parentColName);
		setParentColValue(parentColValue);
		setCheckboxName(checkboxName);
		setWhereClause(whereClause);
	}

	/**
	 * 構造函數
	 * 
	 * @param title
	 * @param tableName
	 * @param colName
	 * @param textColName
	 * @param parentColName
	 * @param parentColValue
	 * @param checkboxName
	 * @param whereClause
	 * @param includeRoot
	 * @throws Exception
	 *             Create Date : 2004-2-9
	 */
	public CheckboxTreeView(String title, String tableName, String colName,
			String textColName, String parentColName, String parentColValue,
			String checkboxName, String whereClause, boolean includeRoot)
			throws Exception {

		setTitle(title);
		setTableName(tableName);
		setColName(colName);
		setTextColName(textColName);
		setParentColName(parentColName);
		setParentColValue(parentColValue);
		setCheckboxName(checkboxName);
		setWhereClause(whereClause);
		setIncludeRoot(includeRoot);
	}

	/**
	 * 構造函數
	 * 
	 * @param title
	 * @param tableName
	 * @param colName
	 * @param textColName
	 * @param parentColName
	 * @param parentColValue
	 * @param checkboxName
	 * @param whereClause
	 * @param checkedValue
	 * @throws Exception
	 *             Create Date : 2004-2-9
	 */
	public CheckboxTreeView(String title, String tableName, String colName,
			String textColName, String parentColName, String parentColValue,
			String checkboxName, String whereClause, String[] checkedValue)
			throws Exception {

		setTitle(title);
		setTableName(tableName);
		setColName(colName);
		setTextColName(textColName);
		setParentColName(parentColName);
		setParentColValue(parentColValue);
		setCheckboxName(checkboxName);
		setWhereClause(whereClause);
		setCheckedValue(checkedValue);
	}

	/**
	 * 構造函數
	 * 
	 * @param title
	 * @param tableName
	 * @param colName
	 * @param textColName
	 * @param parentColName
	 * @param parentColValue
	 * @param checkboxName
	 * @param whereClause
	 * @param checkedValue
	 * @param includeRoot
	 * @throws Exception
	 *             Create Date : 2004-2-9
	 */
	public CheckboxTreeView(String title, String tableName, String colName,
			String textColName, String parentColName, String parentColValue,
			String checkboxName, String whereClause, String[] checkedValue,
			boolean includeRoot) throws Exception {

		setTitle(title);
		setTableName(tableName);
		setColName(colName);
		setTextColName(textColName);
		setParentColName(parentColName);
		setParentColValue(parentColValue);
		setCheckboxName(checkboxName);
		setWhereClause(whereClause);
		setCheckedValue(checkedValue);
		setIncludeRoot(includeRoot);
	}

	/**
	 * 帶“checkbox”或“radio”的樹狀菜單被選中的值的集合
	 */
	private String[] checkedValue = null;

	private Vector vChecked = new Vector();

	/**
	 * 是否不允許修改
	 */
	private boolean disabled = false;

	/**
	 * Root是否也納入Checkbox選框範圍
	 */
	private boolean includeRoot = false;

	/**
	 * 顯示到頁面上的html代碼
	 */
	private StringBuffer html = null;

	/**
	 * 表名
	 */
	private String tableName = null;

	/**
	 * 主欄位名稱
	 */
	private String colName = null;

	/**
	 * 主欄位顯示文字欄位
	 */
	private String textColName = null;

	/**
	 * 父欄位名稱
	 */
	private String parentColName = null;

	/**
	 * 父欄位初始值
	 */
	private String parentColValue = null;

	/**
	 * 顯示的checkbox的名稱
	 */
	private String checkboxName = null;

	/**
	 * 顯示在功能表最頂層的標題
	 */
	private String title = null;

	/**
	 * where條件
	 */
	private String whereClause = null;

	private String imgTreeHead = null;

	private String imgPlus = null;

	private String imgMinus = null;

	private String imgFolder = null;

	private String imgNode = null;

	private String imgTrans = null;

	/**
	 * @return String
	 */
	public String getColName() {
		return colName;
	}

	/**
	 * @return String
	 */
	public String getParentColName() {
		return parentColName;
	}

	/**
	 * @return String
	 */
	public String getParentColValue() {
		return parentColValue;
	}

	/**
	 * @return String
	 */
	public String getTableName() {
		return tableName;
	}

	/**
	 * Sets the colName.
	 * 
	 * @param colName
	 *            The colName to set
	 */
	public void setColName(String colName) {
		this.colName = colName;
	}

	/**
	 * Sets the parentColName.
	 * 
	 * @param parentColName
	 *            The parentColName to set
	 */
	public void setParentColName(String parentColName) {
		this.parentColName = parentColName;
	}

	/**
	 * Sets the parentColValue.
	 * 
	 * @param parentColValue
	 *            The parentColValue to set
	 */
	public void setParentColValue(String parentColValue) {
		this.parentColValue = parentColValue;
	}

	/**
	 * Sets the tableName.
	 * 
	 * @param tableName
	 *            The tableName to set
	 */
	public void setTableName(String tableName) {
		this.tableName = tableName;
	}

	/**
	 * @return String
	 */
	public String getTextColName() {
		return textColName;
	}

	/**
	 * Sets the textColName.
	 * 
	 * @param textColName
	 *            The textColName to set
	 */
	public void setTextColName(String textColName) {
		this.textColName = textColName;
	}

	/**
	 * @return String
	 */
	public String getTitle() {
		return title;
	}

	/**
	 * Sets the title.
	 * 
	 * @param title
	 *            The title to set
	 */
	public void setTitle(String title) {
		this.title = title;
	}

	/**
	 * @return String
	 */
	public String getImgFolder() {
		return imgFolder;
	}

	/**
	 * @return String
	 */
	public String getImgMinus() {
		return imgMinus;
	}

	/**
	 * @return String
	 */
	public String getImgNode() {
		return imgNode;
	}

	/**
	 * @return String
	 */
	public String getImgPlus() {
		return imgPlus;
	}

	/**
	 * @return String
	 */
	public String getImgTrans() {
		return imgTrans;
	}

	/**
	 * @return String
	 */
	public String getImgTreeHead() {
		return imgTreeHead;
	}

	/**
	 * Sets the imgFolder.
	 * 
	 * @param imgFolder
	 *            The imgFolder to set
	 */
	public void setImgFolder(String imgFolder) {
		this.imgFolder = imgFolder;
	}

	/**
	 * Sets the imgMinus.
	 * 
	 * @param imgMinus
	 *            The imgMinus to set
	 */
	public void setImgMinus(String imgMinus) {
		this.imgMinus = imgMinus;
	}

	/**
	 * Sets the imgNode.
	 * 
	 * @param imgNode
	 *            The imgNode to set
	 */
	public void setImgNode(String imgNode) {
		this.imgNode = imgNode;
	}

	/**
	 * Sets the imgPlus.
	 * 
	 * @param imgPlus
	 *            The imgPlus to set
	 */
	public void setImgPlus(String imgPlus) {
		this.imgPlus = imgPlus;
	}

	/**
	 * Sets the imgTrans.
	 * 
	 * @param imgTrans
	 *            The imgTrans to set
	 */
	public void setImgTrans(String imgTrans) {
		this.imgTrans = imgTrans;
	}

	/**
	 * Sets the imgTreeHead.
	 * 
	 * @param imgTreeHead
	 *            The imgTreeHead to set
	 */
	public void setImgTreeHead(String imgTreeHead) {
		this.imgTreeHead = imgTreeHead;
	}

	/**
	 * @return String[]
	 */
	public String[] getCheckedValue() {
		return checkedValue;
	}

	/**
	 * @return String
	 */
	public String getWhereClause() {
		return whereClause;
	}

	/**
	 * Sets the checkValue.
	 * 
	 * @param checkValue
	 *            The checkValue to set
	 */
	public void setCheckedValue(String[] checkedValue) {
		this.checkedValue = checkedValue;
	}

	/**
	 * Sets the whereClause.
	 * 
	 * @param whereClause
	 *            The whereClause to set
	 */
	public void setWhereClause(String whereClause) {
		this.whereClause = whereClause;
	}

	/**
	 * @return String
	 */
	public String getCheckboxName() {
		return checkboxName;
	}

	/**
	 * Sets the checkboxName.
	 * 
	 * @param checkboxName
	 *            The checkboxName to set
	 */
	public void setCheckboxName(String checkboxName) {
		this.checkboxName = checkboxName;
	}

	/**
	 * @return boolean
	 */
	public boolean isIncludeRoot() {
		return includeRoot;
	}

	/**
	 * Sets the includeRoot.
	 * 
	 * @param includeRoot
	 *            The includeRoot to set
	 */
	public void setIncludeRoot(boolean includeRoot) {
		this.includeRoot = includeRoot;
	}

	/**
	 * @return boolean
	 */
	public boolean isDisabled() {
		return disabled;
	}

	/**
	 * Sets the disabled.
	 * 
	 * @param disabled
	 *            The disabled to set
	 */
	public void setDisabled(boolean disabled) {
		this.disabled = disabled;
	}

	/**
	 * 生成javascript中生成樹狀功能表使用的陣列
	 * 
	 * @throws Exception
	 *             Create Date : 2004-1-17
	 */
	public void create() throws Exception {

		setImgTreeHead(this.contexPath + Paras.get("imgTreeHead"));
		setImgPlus(this.contexPath + Paras.get("imgPlus"));
		setImgMinus(this.contexPath + Paras.get("imgMinus"));
		setImgFolder(this.contexPath + Paras.get("imgFolder"));
		setImgNode(this.contexPath + Paras.get("imgNode"));
		setImgTrans(this.contexPath + Paras.get("imgTrans"));

		Statement stmt = null;
		ResultSet rs = null;
		TreeConnection treeConn = new TreeConnection();

		try {
			if (this.checkedValue != null && this.checkedValue.length != 0) {
				for (int i = 0; i < this.checkedValue.length; i++) {
					vChecked.add(this.checkedValue[i]);
				}
			}

			if (this.tableName == null)
				throw new Exception("表名不能為空！");
			if (this.colName == null)
				throw new Exception("主欄位名稱不能為空！");
			if (this.textColName == null)
				throw new Exception("主欄位顯示文字欄位不能為空！");
			if (this.parentColName == null)
				throw new Exception("父欄位名稱不能為空！");
			if (this.parentColValue == null)
				throw new Exception("父欄位初始值不能為空！");

			treeConn.begin();
			newWhereClause = this.getNewWhere(treeConn.getConn());
			html = new StringBuffer();
			html.append("<table border=0 cellspacing=0 cellpadding=0>\n");
			html
					.append("    <tr><td style='padding-left: 0px; display: none'><input type='hidden' name='_CheckboxTreeBegin'></td></tr>\n");

			String title = "";
			if (!this.includeRoot)
				title = "<img src='" + this.imgTreeHead + "' alt='"
						+ this.title + "' align=absmiddle>※" + this.title;
			else
				title = "<input type='checkbox' name='"
						+ this.checkboxName
						+ "' value='"
						+ this.parentColValue
						+ "' class='checkbox' onclick='_clickCheckboxTreeNode( this )'"
						+ (this.disabled ? " disabled" : "") + "><img src='"
						+ this.imgTreeHead + "' alt='" + this.title
						+ "' align=absmiddle>" + this.title;

			html.append("    <tr><td style='padding-left: 0px' nowrap>" + title
					+ "</td></tr>\n");
			recursion(treeConn.getConn(), this.parentColValue,
					this.includeRoot ? 1 : 0);
			html
					.append("    <tr><td style='padding-left: 0px; display: none'><input type='hidden' name='_CheckboxTreeEnd'></td></tr>\n");
			html.append("</table>");

		} catch (SQLException se) {
			se.printStackTrace();
			throw se;
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		} finally {
			try {
				if (rs != null)
					rs.close();
			} catch (Exception e) {
				throw e;
			}
			try {
				if (stmt != null)
					stmt.close();
			} catch (Exception e) {
				throw e;
			}
			try {
				treeConn.free();
			} catch (Exception e) {
				throw e;
			}
		}
	}

	private String newWhereClause = null;

	private String getNewWhere(Connection conn) throws Exception {

		if (this.whereClause == null)
			return null;
		String newWhere = this.colName + " in ('-1'";
		Statement stmt = conn.createStatement();
		String sql = "select " + this.colName + "," + this.parentColName
				+ " from " + this.tableName;
		//System.out.println( "sql::" + sql );

		ResultSet rs = stmt.executeQuery(sql);
		HashMap hm = new HashMap();

		while (rs.next()) {
			//System.out.println( "key:" + rs.getString(1) + " value:" +
			// rs.getString(2) );
			hm.put(convert(rs.getString(1)), convert(rs.getString(2)));
		}
		rs.close();
		stmt.close();

		sql = "select " + this.colName + " from " + this.tableName;
		sql += this.whereClause == null ? "" : (" where " + this.whereClause);

		stmt = conn.createStatement();
		rs = stmt.executeQuery(sql);
		String key = null;
		HashSet hs = new HashSet();
		while (rs.next()) {
			key = convert(rs.getString(1));

			if (hs.contains(key)) {
				continue;
			} else {
				hs.add(key);
			}
			newWhere += ",'" + key + "'";

			if (!key.equals("$$$$$$$$")) {
				while (hm != null && !"$$$$$$$$".equals(hm.get(key))) {
					//System.out.println("1getKey::" + key + "->" + hm.get( key
					// ) + "<-");
					key = hm.get(key).toString();
					//System.out.println("2getKey::" + key + "->" + hm.get( key
					// ) + "<-");
					if (hs.contains(key)) {
						continue;
					} else {
						hs.add(key);
					}
					newWhere += ",'" + key + "'";
					//System.out.println("3getKey::" + key + "->" + hm.get( key
					// ) + "<-");
					if (hm.get(key) == null)
						break;
				}
			}

		}
		stmt.close();
		rs.close();
		newWhere += ")";
		return newWhere;
	}

	/**
	 * 遞迴生成陣列
	 * 
	 * @param conn
	 * @param roleID
	 * @param menuID
	 * @return String
	 * @throws Throwable
	 */
	HashMap rsMap = new HashMap();

	public void recursion(Connection conn, String value, int level) {
		Statement stmt = null;
		ResultSet countRs = null;

		try {
			stmt = conn.createStatement();

			String sql = "";
			String countSql = "";
			sql = "SELECT " + this.colName + ", " + this.textColName + " FROM "
					+ this.tableName + " WHERE " + this.parentColName + " = '"
					+ value + "'";
			sql += this.newWhereClause == null ? ""
					: (" AND " + this.newWhereClause);
			sql += " ORDER BY " + this.parentColName + ", " + this.colName;
			ResultSet rs = stmt.executeQuery(sql);
			boolean hasChild = false;
			ArrayList _arrayList = new ArrayList();

			while (rs.next()) {
				String _code = rs.getString(1);
				String _name = rs.getString(2);
				_arrayList.add(_code + "," + _name);
			}
			rs.close();
			stmt.close();
			for (int i = 0; i < _arrayList.size(); i++) {
				String _tmp = (String) _arrayList.get(i);
				String _code = _tmp.substring(0, _tmp.indexOf(","));
				String _name = _tmp.substring(_tmp.indexOf(",") + 1, _tmp
						.length());
				String checked = vChecked.contains(convert(_code)) ? " checked"
						: "";
				html
						.append("    <tr><td nowrap style='padding-left: "
								+ (level * 18)
								+ "px'><input type='checkbox' name='"
								+ this.checkboxName
								+ "' value='"
								+ convert(_code)
								+ "' class='checkbox' onclick='_clickCheckboxTreeNode( this )'"
								+ checked + (this.disabled ? " disabled" : "")
								+ "><img src='"
								+ (hasChild ? this.imgFolder : this.imgNode)
								+ "' alt='" + convert(_name)
								+ "' align=absmiddle>" + convert(_name)
								+ "</td></tr>\n");
				recursion(conn, convert(_code), level + 1);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}

	}

	/**
	 * 顯示功能表
	 * 
	 * @param out
	 *            Create Date : 2004-1-17
	 */
	public void display(JspWriter out) throws Exception {
		out.println(html.toString());
	}

	private PortalPO convertPo = new PortalPO();

	private String convert(String inputStr) {
		if (inputStr == null) {
			return (null);
		}
		return (convertPo.convert(inputStr));
	}

}
